# -*- coding: utf-8 -*-
"""
# 使用了 [adjustText==1.3.0]，遵循其 [MIT] 许可证，原始代码来源：[https://github.com/Phlya/adjustText]
# 使用了 [matplotlib==3.7.4]，遵循其 [PSF] 许可证，原始代码来源：[https://matplotlib.org]
# 使用了 [numpy==1.24.4]，遵循其 [BSD-3-Clause] 许可证，原始代码来源：[https://www.numpy.org]
# 使用了 [pandas==2.0.3]，遵循其 [BSD 3-Clause License] 许可证，原始代码来源：[https://pandas.pydata.org]
"""
import sys
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
import matplotlib.colors as mcolors
class PARA_CONFIG:
    CURRENT_DIR=Path(__file__).parent.resolve()
    KMEANS_PATH=CURRENT_DIR.parent.parent.resolve()/"03_kmeans"/"src"/"result"/"5_Kmeans_SK_01_kmeans_20251031_150848.xlsx"
    FCHECK_PATH=CURRENT_DIR.parent.parent.resolve()/"04_fcheck"/"src"/"result"/"6_F_check_SK_01_f_check_20251031_151220.xlsx"
    FUNC_PATH=CURRENT_DIR.parent.parent.resolve()/"about_file"
sys.path.append(str(PARA_CONFIG.FUNC_PATH))
import f_basic

def get_text_color(hex_color, threshold=0.6):
    rgb = mcolors.hex2color(hex_color)
    r, g, b = [x * 255 for x in rgb]
    brightness = 0.299*r + 0.587*g + 0.114*b
    return 'white' if (brightness/255 < threshold) else 'black'

def plot_stacked_bar(data, x, y, figsize, rotation=90,label_format="{:.0f}%"):
    colors = ['#FF3333','#FF9933','#FFCC00','#66CC00','#009933','#00CCCC','#0033CC','#9933CC','#CC33CC','#FF3399']
    fig,ax = plt.subplots(figsize=figsize)
    x_positions = np.arange(len(x))
    bar_width = 0.66
    bottom = np.zeros(len(x))
    for i in range(len(y)):
        ax.bar(x_positions, data[:,i], bottom=bottom, width=bar_width,color=colors[i], label=y[i], edgecolor='white', linewidth=0.5)
        for idx in range(len(x)):
            value = data[idx, i]
            if value > 50:
                text_y = bottom[idx] + value / 2
                text_x = x_positions[idx]
                ax.text(
                    text_x, 
                    text_y,
                    label_format.format(value),
                    ha='center',
                    va='center',
                    fontsize=10,
                    rotation=rotation,
                    color=get_text_color(colors[i])
                )
        bottom += data[:, i]
    ax.yaxis.set_major_formatter(PercentFormatter())
    ax.set_xlim(x_positions[0] - 0.5, x_positions[-1] + 0.5)
    ax.set_xticks(x_positions)
    ax.set_xticklabels(x, rotation=rotation,ha='center',va='top')
    ax.legend(loc='upper left', bbox_to_anchor=(1,1), title="主题聚类")
    plt.tight_layout(rect=[0, 0, 0.9, 1])
    return fig, ax
def normalize_columns_to_percentage(data_array):
    arr=np.array(data_array,dtype=float)
    col_sums=arr.sum(axis=0,keepdims=True)
    col_sums[col_sums==0]=1
    normalized=(arr/col_sums)*100
    return normalized

@f_basic.Timer
def draw_stack_bar():
    df_k=pd.read_excel(PARA_CONFIG.KMEANS_PATH)
    df_k.columns=["T#"+str(col) for col in df_k.columns]
    df_k=df_k.rename(columns={"T#label":"label"})
    df_f=pd.read_excel(PARA_CONFIG.FCHECK_PATH)
    li_topics=df_f["Topic"].values.tolist()#get the significant topic list.
    li_info=['label']
    li_topics.extend(li_info)
    li_cluster_label=sorted(df_k['label'].unique())
    cnt_cluster_labels=len(li_cluster_label)
    li_means=[]
    for cluster_label in li_cluster_label:
        df_obj=(df_k.query("label==@cluster_label")[li_topics].drop(columns=["label"],errors='ignore'))
        li_obj=df_obj.mean(skipna=True,axis=0).tolist()
        li_means.append(li_obj)
    np_means=normalize_columns_to_percentage(li_means).T
    topics = [f"主题{i}" for i in range(0,len(li_topics)-1)]
    clusters = [f"聚类{i}" for i in range(0,cnt_cluster_labels)]
    fig,ax=plot_stacked_bar(
        data=np_means,
        x=topics,
        y=clusters,
        figsize=(10,6),
    )
    f_basic.save_figure(fig,prefix="8_Draw_whole_SK")
    plt.show()

if __name__=="__main__":
    draw_stack_bar()